package com.echatim.service.app;

import com.alibaba.fastjson.JSONObject;
import com.annotation.MethodFor;
import com.annotation.TopicFor;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.broker.base.protocol.response.Resp;
import com.commom.DBConst;
import com.commom.Topic;
import com.echatim.dto.HistorySessionDTO;
import com.echatim.dto.MessageListDTO;
import com.echatim.entity.Message;
import com.echatim.entity.Room;
import com.echatim.entity.RoomUser;
import com.echatim.entity.User;
import com.echatim.form.HistoryListForm;
import com.echatim.form.HistoryListSessionForm;
import com.echatim.form.HistoryRoomRecentlyForm;
import com.echatim.mapper.MessageMapper;
import com.utils.Beans;
import com.utils.Streams;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;

import javax.validation.Valid;
import java.util.*;

/**
 * @author kong <androidsimu@163.com>
 * create by 2019/2/21 13:21
 * Description: echatim
 **/


@Slf4j
@ConditionalOnProperty(name="echatim.sdk.auth-type", havingValue="community")
@TopicFor(value = Topic.APP_HISTORY_MESSAGE.name)
@DS("master")
@Service
public class HistoryMessageService extends ServiceImpl<MessageMapper, Message>  {
    @Autowired
    private MessageService messageService;
    @Autowired
    private UserService userService;
    @Autowired
    private RoomUserService roomUserService;
    @Autowired
    private RoomService roomService;

    @MethodFor(value = Topic.APP_HISTORY_MESSAGE.METHOD.LIST_MESSAGE, consumer = HistoryListForm.class)
    public Resp<List<MessageListDTO>> listMessage(@Valid HistoryListForm historyListForm){
        List<Message> messages = new ArrayList<>();
        if(historyListForm.getWay().equals(DBConst.MessageWay.P2P.name())){
            messages = this.getBaseMapper().listHistory(historyListForm);
        }
        else if(historyListForm.getWay().equals(DBConst.MessageWay.P2R.name())){
            messages = this.getBaseMapper().listRoomHistory(historyListForm);
        }
        List<MessageListDTO> dtos = Streams.map(messages, v->Beans.copy(v, MessageListDTO.class)
                .setToMe(historyListForm.getFromUser().equals(v.getFromUser()) ? 0 : 1)
                .setBody(new JSONObject(Beans.str2map(v.getBody()))));
        Map<String, User>  usersMapByAuid = getMessageListUserInfoMap(dtos);
        dtos.forEach(v->{
            if(v.getWay().equals(DBConst.MessageWay.P2P.name())){
                v.setAvatar(v.getToMe() == 0 ?
                        usersMapByAuid.getOrDefault(v.getFromUser(), new User()).getAvatar():
                        usersMapByAuid.getOrDefault(v.getToTarget(), new User()).getAvatar());
                v.setFromUserName(usersMapByAuid.getOrDefault(v.getFromUser(), new User()).getName());
                v.setFromUserAvatar(usersMapByAuid.getOrDefault(v.getFromUser(), new User()).getAvatar());
                v.setToTargetName(usersMapByAuid.getOrDefault(v.getToTarget(), new User()).getName());
                v.setToTargetAvatar(usersMapByAuid.getOrDefault(v.getToTarget(), new User()).getAvatar());
            }
            // 群发送者头像, 名字
            else if(v.getWay().equals(DBConst.MessageWay.P2R.name())){
                v.setAvatar(usersMapByAuid.getOrDefault(v.getFromUser(), new User()).getAvatar());
                v.setFromUserName(usersMapByAuid.getOrDefault(v.getFromUser(), new User()).getName());
                v.setFromUserAvatar(usersMapByAuid.getOrDefault(v.getFromUser(), new User()).getAvatar());
            }
        });


        return Resp.ok(dtos);
    }

    private Map<String, User> getMessageListUserInfoMap(List<MessageListDTO> dtos){
        Set<String> userAuids = new HashSet<String>(){{
            addAll(Streams.keys(dtos, v->v.getFromUser()));
            addAll(Streams.keys(dtos, v->v.getToTarget()));
        }};
        if(userAuids.isEmpty()){
            return Collections.emptyMap();
        }
        List<User> users = userService.lambdaQuery()
                .in(User::getAuid, userAuids)
                .list();
        return  Streams.toMapByKey(users, User::getAuid);
    }

    @MethodFor(value = Topic.APP_HISTORY_MESSAGE.METHOD.LIST_SESSION, consumer = HistoryListSessionForm.class)
    public Resp<List<HistorySessionDTO>> listSessions(HistoryListSessionForm historyListSessionForm) {

        List<HistorySessionDTO> dtos = this.getBaseMapper().listHistorySession(historyListSessionForm);
        List<Long> msgIds = Streams.ids(dtos, HistorySessionDTO::getId);
        if(msgIds.isEmpty()){
            return Resp.ok(Collections.emptyList());
        }
        Map<String, User> usersMapByAuid= getMessageListUserInfoMap(Streams.map(dtos, v->Beans.copy(v, MessageListDTO.class)));
        List<Message> msgs = messageService.lambdaQuery()
                .in(Message::getId, msgIds)
                .list();
        Map<Long, Message> msgsMapById = Streams.toMapById(msgs, Message::getId);
        dtos.forEach(v->{
            v.setBody(new JSONObject(Beans.str2map(msgsMapById.getOrDefault(v.getId(), new Message()).getBody())));
            v.setType(msgsMapById.getOrDefault(v.getId(), new Message()).getType());
            v.setFromUserName("");
            v.setFromUserAvatar("");
            // 消息的发送者是自己, 显示对方头像
            if(v.getFromUser().equals(historyListSessionForm.getAuid())){
                v.setToTargetName(usersMapByAuid.getOrDefault(v.getToTarget(), new User()).getName());
                v.setToTargetAvatar(usersMapByAuid.getOrDefault(v.getToTarget(), new User()).getAvatar());
                v.setToTarget(v.getToTarget());
            }
            // 消息的发送者是别人, 也显示对方头像
            else if(!v.getFromUser().equals(historyListSessionForm.getAuid())){
                v.setToTargetName(usersMapByAuid.getOrDefault(v.getFromUser(), new User()).getName());
                v.setToTargetAvatar(usersMapByAuid.getOrDefault(v.getFromUser(), new User()).getAvatar());
                v.setToTarget(v.getFromUser());
            }
        });
        Map<String, List<HistorySessionDTO>> dtosGroupByTarget = Streams.groupByKey(dtos, v->v.getToTarget());
        List<HistorySessionDTO> recentlyCreateTimeDTOS = new ArrayList<>();
        // 取最新时间的一条数据
        dtosGroupByTarget.forEach((k,v)->{
            recentlyCreateTimeDTOS.add(v.stream().max((Comparator.comparing(HistorySessionDTO::getCreateTime))).orElse(new HistorySessionDTO()));
        });

        return Resp.ok(recentlyCreateTimeDTOS);
    }

    @MethodFor(value = Topic.APP_HISTORY_MESSAGE.METHOD.LIST_ROOM_RECENTLY, consumer = HistoryListSessionForm.class)
    public Resp<List<MessageListDTO>> listRoomRecently(HistoryRoomRecentlyForm form) {
        List<RoomUser> roomUsers = roomUserService.lambdaQuery()
                .eq(RoomUser::getAuid, form.getAuid())
                .list();
        if(roomUsers.isEmpty()){
            return Resp.ok(Collections.emptyList());
        }
        form.setRids(Streams.ids(roomUsers, v->v.getRid()));
        List<Message> msgs = this.getBaseMapper().listRoomRecentlyOne(form);
        if(msgs.isEmpty()){
            return Resp.ok(new ArrayList<>());
        }
        List<MessageListDTO> messageListDTOS = Streams.map(msgs, v->Beans.copy(v, MessageListDTO.class).setBody(new JSONObject(Beans.str2map(v.getBody()))));
        List<Room> rooms = roomService.lambdaQuery()
                .in(Room::getId, Streams.map(messageListDTOS, v->Integer.parseInt(v.getToTarget())))
                .list();
        Map<Long, Room> roomMapById = Streams.toMapById(rooms, v->v.getId());
        messageListDTOS.forEach(v->{
            Room room = roomMapById.getOrDefault(Long.parseLong(v.getToTarget()), new Room());
            v.setToTargetName(room.getName());
            v.setToTargetAvatar(room.getAvatar());
        });
        return Resp.ok(messageListDTOS);
    }
}
